package com.free.ext.shiro.realm;

import com.free.ext.shiro.token.CapatchaUserPwdToken;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.credential.AllowAllCredentialsMatcher;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.realm.AuthenticatingRealm;

/**
 * <p>
 * 功能概述:
 * </p>
 * <p>
 * 功能详述:
 * </p>
 */
public abstract class AbstractAuthenticatingRealm<T> extends AuthenticatingRealm {


    /*========================================================================*
     *                         Public Fields (公共属性)
     *========================================================================*/

    /*========================================================================*
     *                         Private Fields (私有属性)
     *========================================================================*/
    private static final AllowAllCredentialsMatcher ALLOW_ALL = new AllowAllCredentialsMatcher();

    /*========================================================================*
     *                         Construct Methods (构造方法)
     *========================================================================*/

    /*========================================================================*
     *                         Public Methods (公有方法)
     *========================================================================*/
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        CapatchaUserPwdToken token = (CapatchaUserPwdToken) authenticationToken;
        T user = authenticatePrincipal(token);

        // 认证通过后将用户信息设置到 principal 属性，将来可以通过 SecurityUtils.getSubject().getPrincipal() 得到该信息
        return new SimpleAuthenticationInfo(user, user, getName());
    }

    /**
     * 认证情报匹配用（目前不做检查）
     */
    @Override
    public final CredentialsMatcher getCredentialsMatcher()
    {
        // 在 getStoredPrincipal 的同时就进行所有的认证检查，所以这里就不需要做了
        return ALLOW_ALL;
    }

    public abstract T authenticatePrincipal(CapatchaUserPwdToken token) throws AuthenticationException;
    /*========================================================================*
     *                         Private Methods (私有方法)
     *========================================================================*/
}
